package cn.iwit.srv.sys;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import cn.iwit.model.SysFunc;
import cn.iwit.model.SysRole;
import cn.iwit.model.SysUser;
import cn.iwit.model.SysUserRole;
import cn.iwit.model.UserInfo;
import cn.iwit.srv.BaseService;
import cn.iwit.util.BusiException;
import cn.iwit.util.PageInfo;
import cn.iwit.util.SqlUtil;
import cn.iwit.util.Tree;
import cn.iwit.util.TreeNodeUtil;

@Service
public class SysUserService extends BaseService {
	
	public UserInfo loadUserInfo(long userid) throws BusiException {
		UserInfo userInfo = new UserInfo();
		String sql = "select * from sys_user where userid=? ";
		SysUser sysUser = this.queryForObject(sql, new Object[] { userid },SysUser.class);
		if (sysUser == null) {
			throw new BusiException("", "未找到用户信息");
		}
		userInfo.setSysUser(sysUser);
		userInfo.setSysFuncs(findFuncByUser(sysUser));
		return userInfo;
	}

	private List<SysFunc> findFuncByUser(SysUser sysUser) {
		String sql ="";
		Object[] args = new Object[]{};
		if(1 == sysUser.getAdministrator().intValue()){
			sql = "select * from sys_func t3";
		}else{
			sql="select t3.* from  sys_user_role t1,sys_role_func t2,sys_func t3 WHERE t1.userid=? and t1.roleid=t2.roleid and t2.funcid = t3.id";
			args = new Object[] { sysUser.getUserid() };
		}
		sql+=" order by seq ";
		List<SysFunc> sysFuncList = this.queryForList(sql,args ,SysFunc.class);
		return sysFuncList;
	}
	
	public PageInfo<SysUser> findUsers(SysUser sysUser,PageInfo<SysUser> page){
		StringBuffer sqlBuffer= new StringBuffer("SELECT * from sys_user ");
		int totalCnt = this.queryForInt(SqlUtil.getCountSql(sqlBuffer.toString()),null);
		page.setTotal(totalCnt);
		List<SysUser> resultList=new ArrayList<SysUser>();
		List<Object> args = new ArrayList<Object>();
		if(sysUser==null){
			sqlBuffer.append("order by "+page.getOrderBy());
		}else{
			sqlBuffer.append("where 1=1 ");
			if(!StringUtils.isEmpty(sysUser.getCname())){
				sqlBuffer.append(" and cname like  '%"+sysUser.getCname()+"%' ");
				//args.add(" '%"+sysUser.getCname()+"%' ");
			}
			if(!StringUtils.isEmpty(sysUser.getUsername())){
				sqlBuffer.append(" and  username=? ");
				args.add(sysUser.getUsername());
			}
			if(!StringUtils.isEmpty(sysUser.getPassword())){
				sqlBuffer.append(" and  password=? ");
				args.add(sysUser.getPassword());
			}
			if(!StringUtils.isEmpty(sysUser.getUserid())){
				sqlBuffer.append(" and  userid=? ");
				args.add(sysUser.getUserid());
			}
			if(!StringUtils.isEmpty(page.getOrderBy())){
				sqlBuffer.append("order by "+page.getOrderBy());
			}
		}
		resultList = this.queryForList(SqlUtil.getLimitRecord(sqlBuffer.toString(), page.getPageNum(), page.getPageSize()),args.toArray(),SysUser.class);
		page.setList(resultList);
		return page;
	}
	@Transactional(readOnly=false)
	public int saveUser(SysUser sysUser){
		sysUser.setAddtime(new Date());
		sysUser.setModifytime(new Date());
		String sql = "insert into sys_user (username, password, cname, administrator, sex, mobile, email, enabled, remark, adduser, addtime, modifyuser, modifytime, salt, state) select ?,?,?,?,?, ?, ?, ?, ?, ?,?, ?,?,null,'1' from dual where not exists (select * from sys_user t where t.username=?)";
		Object[] args = new Object[]{sysUser.getUsername(),sysUser.getPassword(),sysUser.getCname(),sysUser.getAdministrator(),sysUser.getSex(),sysUser.getMobile(),sysUser.getEmail(),sysUser.getEnabled(),
									 sysUser.getRemark(),sysUser.getAdduser(),sysUser.getAddtime(),sysUser.getModifyuser(),sysUser.getModifytime(),sysUser.getUsername()};
		return this.execUpdate(sql, args);
	}
	
	@Transactional(readOnly=false)
	public void updateUser(SysUser sysUser){
		sysUser.setModifytime(new Date());
		String sql = "update sys_user t set t.email=?,t.password=?,t.sex=?,t.enabled=?,t.administrator=?,t.cname=?,t.mobile=?,t.remark=?,modifyuser=?,t.modifytime=? where t.userid=?";
		Object[] args = new Object[]{sysUser.getEmail(),sysUser.getPassword(),sysUser.getSex(),sysUser.getEnabled(),sysUser.getAdministrator(),sysUser.getCname(),sysUser.getMobile(),sysUser.getRemark(),sysUser.getModifyuser(),sysUser.getModifytime(),sysUser.getUserid()};
		this.execUpdate(sql, args);
	}
	
	@Transactional(readOnly=false)
	public int updatePwd(SysUser sysUser){
		sysUser.setModifytime(new Date());
		String sql = "update sys_user t set t.password=?,modifyuser=?, modifytime=? where t.userid=?";
		Object[] args = new Object[]{sysUser.getPassword(),sysUser.getModifyuser(),sysUser.getModifytime(),sysUser.getUserid()};
		return this.execUpdate(sql, args);
	}
	
	

	@Transactional(readOnly=false)
	public void deleteUserById(String  userid){
		if(!StringUtils.isEmpty(userid)){
			String[] ids = userid.split(",");
			String sql = "delete from sys_user  where userid=? ";
			List<Object[]> args = new ArrayList<Object[]>();
			for(String id :ids){
				args.add(new Object[]{Integer.parseInt(id)});
			}
			this.execBacthUpdate(sql, args);
		}
	}
	
	public PageInfo<SysRole> findRoles(SysRole sysRole,PageInfo<SysRole> page){
		StringBuffer sqlBuffer= new StringBuffer("SELECT * from sys_role ");
		int totalCnt = this.queryForInt(SqlUtil.getCountSql(sqlBuffer.toString()),null);
		page.setTotal(totalCnt);
		List<SysRole> resultList=new ArrayList<SysRole>();
		List<Object> args = new ArrayList<Object>();
		if(sysRole==null){
			sqlBuffer.append("order by "+page.getOrderBy());
		}else{
			sqlBuffer.append("where 1=1 ");
			if(!StringUtils.isEmpty(sysRole.getRolename())){
				sqlBuffer.append(" and rolename like  '%"+sysRole.getRolename()+"%' ");
				//args.add(" '%"+sysUser.getCname()+"%' ");
			}
			if(!StringUtils.isEmpty(sysRole.getRoleid())){
				sqlBuffer.append(" and  roleid = ? ");
				args.add(sysRole.getRoleid());
			}
			sqlBuffer.append("order by "+page.getOrderBy());
		}
		resultList = this.queryForList(SqlUtil.getLimitRecord(sqlBuffer.toString(), page.getPageNum(), page.getPageSize()),args.toArray(),SysRole.class);
		page.setList(resultList);
		return page;
	} 
	
	@Transactional(readOnly=false)
	public void saveRole(SysRole sysRole){
		String sql = "insert into sys_role (rolename, described, seq, adduser, addtime, modifyuser, modifytime) values ( ?, ?, ?, ?, ?,?, ?)";
		sysRole.setAddtime(new Date());
		sysRole.setModifytime(new Date());
		Object[] args = new Object[]{sysRole.getRolename(),sysRole.getDescribed(),sysRole.getSeq(),sysRole.getAdduser(),sysRole.getAddtime(),sysRole.getModifyuser(),sysRole.getModifytime()};
		this.execUpdate(sql, args);
	}
	
	@Transactional(readOnly=false)
	public void updateRole(SysRole sysRole){
		String sql = "update sys_role t set t.rolename=?,t.described=?,t.modifytime=? where t.roleid=?";
		sysRole.setModifytime(new Date());
		Object[] args = new Object[]{sysRole.getRolename(),sysRole.getDescribed(),sysRole.getModifytime(),sysRole.getRoleid()};
		this.execUpdate(sql, args);
	}
	
	@Transactional(readOnly=false)
	public int[] deleteRoleById(String  roleid){
		if(!StringUtils.isEmpty(roleid)){
			String[] ids = roleid.split(",");
			String sql = "delete from sys_role  where roleid=? ";
			List<Object[]> args = new ArrayList<Object[]>();
			for(String id :ids){
				args.add(new Object[]{Integer.parseInt(id)});
			}
			return this.execBacthUpdate(sql, args);
		}
		return new int[]{};
	}
	
	public  List<SysUserRole> findUserRole(SysUserRole userRole){
		String sql="select * from sys_user_role t where t.roleid=?";
		return this.queryForList(sql, new Object[]{userRole.getRoleid()}, SysUserRole.class);
	}
	
	@Transactional(readOnly=false)
	public int saveUserRole(long roleId, long[] userId){
		String sql="delete from  sys_user_role  where roleid=?";
		this.execUpdate(sql, new Object[]{roleId});
		sql="insert into sys_user_role (roleid,userid) values (?,?)";
		List<Object[]> args = new ArrayList<Object[]>();
		for(long id :userId){
			args.add(new Object[]{roleId,id});
		}
		return this.execBacthUpdate(sql, args).length;
	}
	
	 public List<Tree> findFuncByRoleId(long roleid) throws BusiException  {
	        String sql="select t.*,t1.*,if(t1.roleid>0,'1',0) checked from sys_func  t left join sys_role_func  t1 on  t.id=t1.funcid and t1.roleid=? ";
	        List<Map<String, Object>> list = this.query(sql, new Object[]{roleid});
	        List<Tree> treeList = new ArrayList<>();
	        for (Map<String, Object> map : list) {
	            Tree tree = new Tree();
	            tree.setId(map.get("id").toString());
	            tree.setText(map.get("funcname").toString());
	            tree.setIcon(map.get("icon").toString());
	            tree.setUrl(map.get("url").toString());
	            tree.setPid(map.get("parentid").toString());
	            if(map.get("checked")!=null && map.get("checked").toString().equals("1")){
	                tree.setChecked(true);
	            }else {
	                tree.setChecked(false);
	            }
	            treeList.add(tree);
	        }
	        return TreeNodeUtil.getfatherNode(treeList);
	 }
	 
	 @Transactional(readOnly=false)
	public int saveRoleFunc(long roleId, long[] funcId){
		String sql="delete from  sys_role_func  where roleid=?";
		this.execUpdate(sql, new Object[]{roleId});
		sql="insert into sys_role_func (roleid,funcid) values (?,?)";
		List<Object[]> args = new ArrayList<Object[]>();
		for(long id :funcId){
			args.add(new Object[]{roleId,id});
		}
		return this.execBacthUpdate(sql, args).length;
	}
	 
	public List<SysFunc> findFuncList(SysFunc sysFunc){
		StringBuffer sqlBuffer= new StringBuffer("select * from sys_func ");
		List<Object> args = new ArrayList<Object>();
		if(sysFunc!=null){
			sqlBuffer.append(" where 1=1 ");
			if(!StringUtils.isEmpty(sysFunc.getFuncname())){
				sqlBuffer.append(" and funcname like  '%"+sysFunc.getFuncname()+"%' ");
			}
		}
		return this.queryForList(sqlBuffer.toString(), args.toArray(), SysFunc.class);
	}
	
	@Transactional(readOnly=false)
	public int saveFunc(SysFunc sysFunc){
		String sql="insert into sys_func (funcname, siteid, url, ismenu, icon, seq, described, parentid, adduser, addtime, modifyuser, modifytime) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)";
		return this.execUpdate(sql, new Object[]{sysFunc.getFuncname(),sysFunc.getSiteid(),sysFunc.getUrl(),sysFunc.getIsmenu(),sysFunc.getIcon(),sysFunc.getSeq(),sysFunc.getDescribed(),sysFunc.getParentid(),sysFunc.getAdduser(),sysFunc.getAddtime(),sysFunc.getModifyuser(),sysFunc.getModifytime()});
	}
	@Transactional(readOnly=false)
	public int updateFunc(SysFunc sysFunc){
		String sql="update sys_func set funcname=?,parentid=?,ismenu=?,icon=?,url=?,seq=?,described=? where id=?";
		return this.execUpdate(sql, new Object[]{sysFunc.getFuncname(),sysFunc.getParentid(),sysFunc.getIsmenu(),sysFunc.getIcon(),sysFunc.getUrl(),sysFunc.getSeq(),sysFunc.getDescribed(),sysFunc.getId()});
	}
	
	@Transactional(readOnly=false)
	public int[] deleteFunc(String funcId){
		if(!StringUtils.isEmpty(funcId)){
			String[] ids = funcId.split(",");
			String sql = "delete from sys_func  where id=? ";
			List<Object[]> args = new ArrayList<Object[]>();
			for(String id :ids){
				args.add(new Object[]{Integer.parseInt(id)});
			}
			return this.execBacthUpdate(sql, args);
		}
		return new int[]{};
	}
}
